﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows;

//buddy
using Zeta;
using Zeta.Common;
using Zeta.CommonBot;
using Zeta.Common.Plugins;
using Zeta.Internals;
using Zeta.Internals.Actors;
using Zeta.Internals.Service;

namespace BossHog
{
    public delegate void EmptyDelegate();
    public delegate void VectorDelegate(Vector3 v);

    public class BossHogPlugin : IPlugin
    {
        [STAThread()]
        static void Main(string[] args)
        {
            System.Windows.Forms.Application.Run(new Toolkit());
        }

        Toolkit tool = null;
        public bool ForcingMove { get; set; }
        public DateTime LastPositionChange { get; set; }
        public Vector3 LastPosition { get; set; }
        public List<Vector3> GameMovements { get; set; }
        Zeta.Internals.Actors.DiaPlayer Me { get { return ZetaDia.Me; } }

        #region BotEvents
        void GameEvents_OnWorldChanged(object sender, EventArgs e)
        {
            Logging.Write(LogLevel.Verbose, "[BossHog] GameEvents_OnWorldChanged.");
            ResetUnstucker();
        }

        void GameEvents_OnGameLeft(object sender, EventArgs e)
        {
            Logging.Write(LogLevel.Verbose, "[BossHog] GameEvents_OnGameLeft.");
            ResetUnstucker();
        }

        void GameEvents_OnGameJoined(object sender, EventArgs e)
        {
            Logging.Write(LogLevel.Verbose, "[BossHog] GameEvents_OnGameJoined.");
            //ResetUnstucker();
        }

        void BotMain_OnStop(IBot bot)
        {
            Logging.Write(LogLevel.Verbose, "[BossHog] BotMain_OnStop.");
            //StopScaning();
        }

        void BotMain_OnStart(IBot bot)
        {
            Logging.Write(LogLevel.Verbose, "[BossHog] BotMain_OnStart.");
            ResetUnstucker();
            //BeginScaning();
        }
        #endregion
        #region IPlugin
        public string Author { get { return "xsol"; } }
        public string Description { get { return ""; } }
        public string Name { get { return "BossHog Toolkit"; } }
        public Version Version { get { return new Version(1, 0, 7); } }
        public Window DisplayWindow { get { return null; } }


        public void ResetUnstucker()
        {
            ForcingMove = false;
            LastPositionChange = DateTime.Now;
            LastPosition = (null == Me) ? new Vector3() : Me.Position;
            GameMovements = new List<Vector3>();

            if (null != tool) tool.BeginInvoke(
                new EmptyDelegate(tool.ClearPositionLog));

        }

        public void OnInitialize()
        {
            EnableUnstucker = false;
            ResetUnstucker();
        }

        public void OnShutdown()
        {
            if (null != tool)
            {
                tool.Close();
                tool.Dispose();
                tool = null;
            }

            //StopScaning();
        }

        public void OnEnabled()
        {
            Logging.Write(LogLevel.Verbose, "[BossHog] Enabled.");

            BotMain.OnStart += new BotEvent(BotMain_OnStart);
            BotMain.OnStop += new BotEvent(BotMain_OnStop);

            Zeta.CommonBot.GameEvents.OnGameJoined += new EventHandler<EventArgs>(GameEvents_OnGameJoined);
            Zeta.CommonBot.GameEvents.OnGameLeft += new EventHandler<EventArgs>(GameEvents_OnGameLeft);
            Zeta.CommonBot.GameEvents.OnWorldChanged += new EventHandler<EventArgs>(GameEvents_OnWorldChanged);

            try
            {
                tool = new Toolkit();
                tool.Show();
            }
            catch (Exception ex){Logging.Write(LogLevel.Verbose, "[BossHog] Error: " + ex.Message);}

            //BeginScaning(); //start the thread that monitors pathing

        }

        public void OnDisabled()
        {
            Logging.Write(LogLevel.Verbose, "[BossHog] Disabled.");
            if (null != tool)
            {
                tool.Close();
                tool.Dispose();
                tool = null;
            }

            //StopScaning();
        }

        public bool Equals(IPlugin other)
        {
            return (other.Name == Name) && (other.Version == Version);
        }

        public static bool EnableUnstucker { get; set; }
        #endregion

        public void OnPulse()
        {
            if (!ZetaDia.IsInGame || !ZetaDia.Me.IsValid)
            {
                
            }
            else
            {
                if (null != tool)
                {

                    //try to avoid any locking blocking issues
                    tool.BeginInvoke(new EmptyDelegate(tool.PluginPulse)); //pulse for updates

                    #region Move Tracking/Stuck Handling
                    if (DateTime.Now.Subtract(LastPositionChange).TotalSeconds >= 4)
                    {
                        if (Me.Position.Distance(LastPosition) >= 40)
                        {
                            LastPosition = Me.Position;
                            GameMovements.Add(LastPosition);

                            tool.BeginInvoke(
                                new VectorDelegate(tool.TrackPosition), 
                                new object[]{LastPosition});

                            LastPositionChange = DateTime.Now;
                        }
                        else if (Me.Position.Distance(LastPosition) <= 40)
                        {   //give it time to fight and move the 40 yards
                            //if (!ForcingMove && EnableUnstucker && DateTime.Now.Subtract(LastPositionChange).TotalSeconds >= (60*3))
                            //{
                            //    if (null != GameMovements && GameMovements.Count > 1)
                            //    {
                            //        tool.BeginInvoke(new EmptyDelegate(tool.ReloadRestart), new object[] { });
                            //    }
                            //}
                        } //(Me.Position.Distance(LastPosition) >= 10)
                    } //(DateTime.Now.Subtract(LastPositionChange).TotalSeconds >= 4)
                    #endregion

                }//(null != tool)
            }//(!ZetaDia.IsInGame || !ZetaDia.Me.IsValid)
        }

        #region Monitor Thread
        //System.Threading.Thread gameChecker = null;
        //bool scanning = false;

        //void BeginScaning()
        //{
        //    scanning = true;
        //    gameChecker = new System.Threading.Thread(new System.Threading.ThreadStart(GameMonitor));
        //    gameChecker.Start();
        //}
        //void GameMonitor()
        //{
        //    while (scanning)
        //    {
        //        try
        //        {
        //            if (!ZetaDia.IsInGame || ZetaDia.IsLoadingWorld || null == ZetaDia.Me)
        //            {
        //                ResetUnstucker();
        //                System.Threading.Thread.Sleep(1000);
        //            }
        //        }
        //        catch (Exception ex) { Logging.Write(LogLevel.Verbose, "[BossHog] Error: " + ex.Message); }
        //    }
        //}
        //void StopScaning()
        //{
        //    scanning = false;
        //    System.Threading.Thread.Sleep(350);
        //    try
        //    {
        //        gameChecker.Abort();
        //        gameChecker = null;
        //    }
        //    catch (Exception ex) { Logging.Write(LogLevel.Verbose, "[BossHog] Error: " + ex.Message); }
        //}
        #endregion

    }
}
